"""
* Author       : Isidore
* Date         : 2022-08-26 14:58:12
* LastEditors  : Isidore
* LastEditTime : 2022-09-02 19:34:45
* Description  : file content
* FilePath     : /Workspace/vika_md.py
"""
from vika import Vika
import pandas as pd
import os
import time
from tqdm.auto import tqdm
import re
import siyuan_md


def content_adder(string, property, content, func, *args, **kwargs):
    if property in property_ref_df_dict:
        args = [property_ref_df_dict[property]] + list(args)
    if property in admonition_dict:
        args = [admonition_dict[property]] + list(args)
    if not isinstance(content, list) and not pd.isna(content):
        string = func(string, content, *args, **kwargs)
    elif isinstance(content, list) and not pd.isna(content).all():
        string = func(string, content, *args, **kwargs)
    string += "\n"

    return string


def logseq_page_property(func):
    def wrapper(string, property, content, *args, **kwargs):
        string = string + property + "::  "
        string = content_adder(string, property, content, func, *args, **kwargs)
        return string

    return wrapper


@logseq_page_property
def plain_property_adder(string, content):
    string = string + content
    return string


@logseq_page_property
def date_property_adder(string, content):
    t_struct = time.localtime(content / 1000)
    string += f"[[{t_struct.tm_mon:2d}-{t_struct.tm_mday}-{t_struct.tm_year}]]"
    return string


@logseq_page_property
def year_property_adder(string, content):
    if content < 0:
        return string
    t_struct = time.localtime(content / 1000)
    string += f"{t_struct.tm_year}"
    return string


@logseq_page_property
def page_lis_property_adder(string, content):
    for item in content:
        string = string + "[[" + item + "]]" + ", "
    return string[:-2]


@logseq_page_property
def page_property_adder(string, content):
    string = string + "[[" + content + "]]"
    return string


def logseq_page_body(func):
    def wrapper(string, property, content, *args, **kwargs):
        string = string + "\n" + "## " + property.title() + "\n"
        string = content_adder(string, property, content, func, *args, **kwargs)
        string += "\n"
        return string

    return wrapper


@logseq_page_property
def ref_lis_property_adder(string, content, outer_df):
    title_lis = outer_df.loc[outer_df["id"].isin(content), "title"].tolist()
    for item in title_lis:
        string = string + "[[" + item + "]]" + ", "
    return string[:-2]


def body_cleaning(body):
    body = re.sub(r"\n\[\*+ *METHOD *\*+\]\n", "\n", body, flags=re.IGNORECASE | re.UNICODE)
    body = re.sub(r"\n\[\*+ *EXPERIMENT[S]? *\*+\]\n", "\n## #Experiment\n\n", body, flags=re.IGNORECASE | re.UNICODE)
    body = re.sub(r"\n\[\*+ *IDEA[S]? *\*+\]\n", "\n## #Idea\n\n", body, flags=re.IGNORECASE | re.UNICODE)
    return body


@logseq_page_body
def plain_body_adder(string, content):
    content = body_cleaning(content)
    string = string + content
    return string


@logseq_page_body
def admonition_body_adder(string, content, admonition_type):
    admonition_type = admonition_type.upper()
    string += f"""#+BEGIN_{admonition_type}
{body_cleaning(content)}
#+END_{admonition_type}"""
    return string


@logseq_page_body
def image_body_adder(string, info_list):
    for item in info_list:
        string = string + f"![]({item['url']})"
    return string


@logseq_page_body
def alias_body_adder(string, content, outer_df):
    alias_df = outer_df[["alias", "title"]][outer_df["id"].isin(content)]
    replace_idx = pd.isna(alias_df["alias"])
    alias_df["alias"][replace_idx] = alias_df["title"][replace_idx]
    for item in alias_df["alias"].tolist():
        string = string + "[[" + item + "]]" + "\n"
    return string[:-1]


def note_framework(rec, processor_dict, process_type, write=False):
    tqdm.write(rec["title"])
    note_string = f"type:: [[{process_type}]]\n"
    for property, process in processor_dict.items():
        note_string = process(note_string, property, rec[property])
    if write is True:
        file_name = rec["title"].translate("".maketrans(":?>", "   ")).strip()
        file_name = file_name.replace("  ", " ")
        file_name = re.sub(invalid_char, "", file_name)
        with open(f"vika-md/{process_type}/{file_name}.md", "w", encoding="utf8") as f:
            f.write(re.sub(invalid_char, "", note_string))
    return note_string


def get_df(sht_id, view_id):
    dst = vika.datasheet(sht_id)
    records = dst.records.all(viewId=view_id)
    df = pd.DataFrame([record.json() for record in records])
    df["id"] = [record._id for record in records]
    return df


paper_processor_dict = {
    "title": plain_property_adder,
    "alias": plain_property_adder,
    "ac-task": ref_lis_property_adder,
    "ac-genre": page_lis_property_adder,
    "ac-publisher": ref_lis_property_adder,
    "year": year_property_adder,
    "person": ref_lis_property_adder,
    "laboratory": ref_lis_property_adder,
    "dataset": ref_lis_property_adder,
    "status": page_property_adder,
    "start_date": date_property_adder,
    "end_date": date_property_adder,
    "ac-project": ref_lis_property_adder,
    "framework": image_body_adder,
    "Past": plain_body_adder,
    "Method": plain_body_adder,
    "outcome": image_body_adder,
    "Note": plain_body_adder,
    "correlation": alias_body_adder,
    "OnGoing": plain_body_adder,
}


project_processor_dict = {"title": plain_property_adder, "ac-genre": page_lis_property_adder, "description": admonition_body_adder}

publisher_processor_dict = {
    "title": plain_property_adder,
    "level": page_property_adder,
    "alias": plain_property_adder,
    "start-time": date_property_adder,
    "end-time": date_property_adder,
}

dataset_processor_dict = {
    "title": plain_property_adder,
    "alias": plain_property_adder,
    "url": plain_property_adder,
    "ac-task": ref_lis_property_adder,
    "paper": ref_lis_property_adder,
    "description": admonition_body_adder,
}

task_processor_dict = {
    "title": plain_property_adder,
    "alias": plain_property_adder,
    "description": admonition_body_adder,
}

laboratory_processor_dict = {"title": plain_property_adder, "organization": page_property_adder, "person": ref_lis_property_adder}

invalid_char = r"[\x00\x02\x08\x0B\x0C\x0E-\x1F]+"


vika = Vika("uskusRPT5VzNaInKzMBJoz0")
paper_df = get_df("dstat54wzBmzF96g7Z", "viwZgf534vmub")
task_df = get_df("dstQQxW6ZYhLi7TYf5", "viw9lnSCrDs49")
project_df = get_df("dstX42iYFGP6z1gmBV", "viwawT9Oz7Pls")
publisher_df = get_df("dstoaEesGgHhzokiwi", "viwqfELBfxCFF")
dataset_df = get_df("dstQYP1PcihYmYrpgD", "viw3QBy5UQYml")
laboratory_df = get_df("dstEuZoM2HX6u7CZEM", "viwTlWKMYAMLB")
person_df = get_df("dst02AobleGKwxzhuR", "viwCf6hCBF6Fs")

# task_df, publisher_df, laboratory_df, project_df = paper_df, paper_df, paper_df, paper_df
property_ref_df_dict = {
    "ac-task": task_df,
    "ac-publisher": publisher_df,
    "person": person_df,
    "laboratory": laboratory_df,
    "dataset": dataset_df,
    "ac-project": project_df,
    "correlation": paper_df,
    "paper": paper_df,
}
admonition_dict = {"description": "NOTE"}

processor_dict_list = [
    dataset_processor_dict,
    paper_processor_dict,
    project_processor_dict,
    task_processor_dict,
    publisher_processor_dict,
    laboratory_processor_dict,
]
processor_df_list = [dataset_df, paper_df, project_df, task_df, publisher_df, laboratory_df]
processor_type_list = ["dataset", "paper", "ac-project", "ac-task", "ac-publisher", "laboratory"]


def main():

    for processor_df, processor_dict, processor_type in zip(processor_df_list, processor_dict_list, processor_type_list):
        os.makedirs(os.path.join("vika-md", processor_type), exist_ok=True)
        tqdm.pandas(desc=processor_type)
        processor_df.progress_apply(note_framework, axis=1, args=[processor_dict, processor_type, True])

    note_dir = "vika-md"
    os.makedirs(os.path.join("vika-md", "assets"), exist_ok=True)
    file_df = siyuan_md.get_file_df(note_dir)
    siyuan_md.replace_numbered_list(file_df)
    siyuan_md.remove_multi_empty_lines(file_df)
    siyuan_md.replace_image_anchor(file_df)
    siyuan_md.move_local_image(file_df, note_dir)
    siyuan_md.move_online_image(note_dir, file_df)
    siyuan_md.replace_nested_url(file_df)
    siyuan_md.remove_image_pre_blank(file_df)
    siyuan_md.replace_double_eq(file_df)


if __name__ == "__main__":
    main()
